package com.cyy.algovis

import javafx.animation.AnimationTimer
import javafx.scene.paint.Color
import javafx.scene.shape.Circle
import javafx.util.Duration
import tornadofx.*

class 蒙特卡洛算法求Pi : View("learn 蒙特卡洛算法") {

    //    动画计时器
    val aniTimer = AniTimer(this)
    val result = stringProperty()
    val numPoint = intProperty()
    val Msg = stringProperty()
    val numPointInCircle = intProperty()
    lateinit var circle0: Circle
    override val root = borderpane {
        top = vbox(5) {
            label(result) {
                isWrapText = true
            }
            label(Msg)
            hbox(5) {
                button("run").action {
                    //                ani()
                    aniTimer.start()
                }
                button("stop").action {
                    //                ani()
                    aniTimer.stop()
                }
            }
        }
        center = group {
            rectangle(0, 0, 600, 600) {
                fill = Color.YELLOW
            }
            circle0 = circle(300, 300, 300) {
                fill = Color.AZURE
            }
            prefHeight = 800.0
            prefWidth = 800.0
        }
    }

    fun paint() {
        timeline {
            keyframe(Duration.seconds(0.0010)) {
                //  用循环包裹，可以调节绘制速度
                (0..100).forEach {
                    val p = point((0..600).random().toDouble(), (0..600).random().toDouble())
                    val c = Circle(p.x, p.y, 1.0)
//                判断圆circle0是否包含点p，方法1
//                val b = ((p.x - circle0.centerX).pow(2).plus((p.y - circle0.centerY).pow(2)) <= circle0.radius.pow(2))
//                if (b) {
//                    c.fill = Color.RED
//                }
                    //  判断圆circle0是否包含点p，方法2
                    if (circle0.contains(p)) {
                        c.fill = Color.RED
                        numPointInCircle.value++
                    }
                    root.center.add(c)
                    numPoint.value++
                    val piEstimate = 4.0 * numPointInCircle.value/ numPoint.value
                    Msg.value = "总点数：${numPoint.value} -- 圆内点数：${numPointInCircle.value} -- Pi估计值:  ${piEstimate} "
                }
            }
        }
    }

    // 此方法可以停止动画
    class AniTimer(val learnV: 蒙特卡洛算法求Pi) : AnimationTimer() {
        var lastTime = 0L
        override fun handle(now: Long) {
            if ((now - lastTime) > 10000000) {
                lastTime = now
            } else {
                return
            }
            learnV.paint()
        }
    }
}

//
//控制台输出版本：
//
//import javafx.scene.paint.Color
//import javafx.scene.shape.Circle
//import tornadofx.*
//
//
//
//fun main(){
//    // 矩形边长
//    val recWidth=1000
//    val r=recWidth/2.toDouble()
//    val circle0 = Circle(r, r.toDouble(), r)
//
////    总点数
//    val numPoint = intProperty()
////    圆内点数
//    val numPointInCircle = intProperty()
//    val Msg = stringProperty()
//
////    1000万个点
//    val n=10000000
//    (0..n).forEach {
//        val p = point((0..recWidth).random().toDouble(), (0..recWidth).random().toDouble())
//        val c = Circle(p.x, p.y, 1.0)
////                判断圆circle0是否包含点p，方法1
////                val b = ((p.x - circle0.centerX).pow(2).plus((p.y - circle0.centerY).pow(2)) <= circle0.radius.pow(2))
////                if (b) {
////                    c.fill = Color.RED
////                }
//        //  判断圆circle0是否包含点p，方法2
//        if (circle0.contains(p)) {
//            c.fill = Color.RED
//            numPointInCircle.value++
//        }
//        numPoint.value++
//        val piEstimate = 4.0 * numPointInCircle.value/ numPoint.value
////        每隔1万个点输出一次
//        if(numPoint.value/10000==1){
//            Msg.value = "总点数：${numPoint.value} -- 圆内点数：${numPointInCircle.value} -- Pi估计值:  ${piEstimate} "
//            println(Msg.value)
//        }
//    }
//}